/*
 * Copyright (C) 2012 Rothens
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rpg.gfx;

import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.LinkedList;
import rpg.util.ImageUtil;
import rpg.util.TextUtil;

/**
 * rothens.tumblr.com
 *
 * @author Rothens
 */
public class FontSets {

    HashMap<Byte, Font> fonts = new HashMap<Byte, Font>();

    public class Font {

        protected HashMap<Character, Bitmap> chars = new HashMap<Character, Bitmap>();
        int width, height, spacing;
        boolean oneCase;

        public Font(String text, BufferedImage img, int width, int height, int spacing, boolean oneCase, int cols) {
            this.height = height;
            this.width = width;
            this.spacing = spacing;

            int act = 0;
            for (char c : text.toCharArray()) {
                int col = act % cols;
                int row = act / cols;
                Bitmap n = ImageUtil.getSubTile(img, row, col, width, height);
                chars.put(c, n);
                act++;
            }
            chars.put(' ', new Bitmap(width, height));
        }

        public Bitmap writeText(String text) {
            text = text.replaceAll("§[0-9A-Fa-f]{1,6}\\s", "");
            int w = text.length() * width + (text.length() - 1) * spacing;
            Bitmap b = new Bitmap(w, height);
            int i = 0;
            for (char c : text.toCharArray()) {
                Bitmap bm = chars.get(c);
                if (bm == null) {
                    bm = new Bitmap(width, height);
                }
                b.draw(bm, i * width + i * spacing, 0);
                i++;
            }
            return b;
        }
    }

    public class ColorableFont extends Font {

        int fromColor;

        public ColorableFont(String text, BufferedImage img, int width, int height, int spacing, boolean oneCase, int cols, int fromColor) {
            super(text, img, width, height, spacing, oneCase, cols);
            this.fromColor = fromColor;
        }

        public Bitmap writeColoredText(String text, int color) {
            String esc = text.replaceAll("§[0-9A-Fa-f]{1,6}\\s", "");
            int w = esc.length() * width + (esc.length() - 1) * spacing;
            Bitmap b = new Bitmap(w, height);
            int i = 0;
            try {
                for (int j = 0; j < text.length(); ++j) {
                    char c = text.charAt(j);
                    if (c == '§') {
                        ++j;
                        String newCol = "";
                        int k = j + 7;
                        while (j < k) {
                            Character t = text.charAt(j);
                            if (t != ' ') {
                                newCol += t;
                            }
                            ++j;
                        }
                        color = Integer.parseInt(newCol, 16) | 0xff000000;
                        c = text.charAt(j);
                    }


                    Bitmap bm = chars.get(c);
                    if (bm == null) {
                        bm = new Bitmap(width, height);
                    }
                    b.draw(bm.simpleRecolor(fromColor, color), i * width + i * spacing, 0);
                    ++i;
                }
            } catch (StringIndexOutOfBoundsException ex) {
            }
            return b;
        }
    }

    public FontSets() {
        String text = "abcdefghijklmnopqrstuvwxyz"
                + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                + "0123456789:+-?!.,<>()\\/&# ";
        BufferedImage bimg = ImageUtil.createImageIcon("/res/fonts/testfont.png");
        fonts.put((byte) 0, new Font(text, bimg, 10, 20, 1, false, 26));
        bimg = ImageUtil.createImageIcon("/res/fonts/testfont2.png");
        fonts.put((byte) 1, new ColorableFont(text, bimg, 25, 27, 1, false, 26, -16777216));
        text += "öüóőúéáűíÖÜÓŐÚÉÁŰÍ@[]*{}\"'";
        bimg = ImageUtil.createImageIcon("/res/fonts/chatfont.png");
        fonts.put((byte) 2, new ColorableFont(text, bimg, 10, 20, 1, false, 26, -16777216));
        bimg = ImageUtil.createImageIcon("/res/fonts/chatfontoutlined.png");
        fonts.put((byte) 3, new ColorableFont(text, bimg, 10, 20, 0, false, 26, -16777216));
        text = "abcdefghijklmnopqrstuvwxyz"
                + "0123456789:+?!,<>()\\/&# "
                + "öüóőúéáűí@[]{}\"'";
        bimg = ImageUtil.createImageIcon("/res/fonts/menufont2.png");
        fonts.put((byte) 4, new ColorableFont(text, bimg, 38, 48, 0, true, 10, -16777216));

    }

    public Bitmap getText(String text, byte id) {
        Font f = fonts.get(id);
        if (f == null) {
            return null;
        }
        return f.writeText(text);
    }

    public Bitmap getText(String text, byte id, int color) {
        if (text.isEmpty()) {
            return null;
        }
        Font f = fonts.get(id);
        if (f == null) {
            return null;
        }
        return (f instanceof ColorableFont) ? ((ColorableFont) f).writeColoredText(text, color) : f.writeText(text);
    }

    public int getHeight(byte id) {
        Font f = fonts.get(id);
        if (f == null) {
            return 0;
        }
        return f.height;
    }

    public int getWidth(byte id) {
        Font f = fonts.get(id);
        if (f == null) {
            return 0;
        }
        return f.width + f.spacing;
    }

    public Bitmap getMultilineText(String text, byte id, int width, int linespacing){
        return getMultilineText(text, id, width, linespacing, TextAlign.LEFT);
    }
    
    public Bitmap getMultilineText(String text, byte id, int width, int linespacing, TextAlign align){
        int maxChar = (int) Math.floor(width/getWidth(id));
        LinkedList<String> lines = TextUtil.wrapText(text, maxChar);     
        Bitmap b = new Bitmap(width, (lines.size()-1)*linespacing + lines.size()*getHeight(id));
        int y = 0;
        for(String s: lines){
            Bitmap line = getText(s, id);
            switch(align){
                case LEFT:
                    b.draw(line, 0, y);
                    break;
                case RIGHT:
                    b.draw(line,width-b.width, y);
                    break;
                case CENTER:
                    b.draw(line,width/2-b.width/2, y);
                    break;
            }
            y+= getHeight(id) + linespacing;
        }
        
        return b;
    }
    
    public Bitmap getMultilineText(String text, byte id, int width, int color, int linespacing){
        return getMultilineText(text, id, width, color, linespacing, TextAlign.LEFT);
    }
    
    public Bitmap getMultilineText(String text, byte id, int width, int color, int linespacing, TextAlign align){
        int maxChar = width/getWidth(id);
        LinkedList<String> lines = TextUtil.wrapText(text, maxChar);     
        Bitmap b = new Bitmap(width, (lines.size()-1)*linespacing + lines.size()*getHeight(id));
        int y = 0;
        for(String s: lines){
            Bitmap line = getText(s, id, color);
            switch(align){
                case LEFT:
                    b.draw(line, 0, y);
                    break;
                case RIGHT:
                    b.draw(line,width-line.width, y);
                    break;
                case CENTER:
                    b.draw(line,width/2-line.width/2, y);
                    break;
            }
            y+= getHeight(id) + linespacing;
        }
        
        return b;
    }
}
